package com.ding.manager.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ding.manager.util.HttpUtils;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.taobao.api.FileItem;
import com.taobao.api.internal.util.WebUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 钉钉工具类
 */
@Component
public class DTConstant {
    static Logger logger = Logger.getLogger(DTConstant.class);


    public static String SNS_GETTOKEN_URL  = "https://oapi.dingtalk.com/sns/gettoken"; //获取钉钉开放应用的ACCESS_TOKEN

    public static String GET_PERSISTENT_CODE_URL  = "https://oapi.dingtalk.com/sns/get_persistent_code";  //获取用户授权的持久授权码

    public static String GET_SNS_TOKEN_URL  = "https://oapi.dingtalk.com/sns/get_sns_token";   //获取用户授权的SNS_TOKEN

    public static String GETUSERINFO_URL  = "https://oapi.dingtalk.com/sns/getuserinfo";   //获取用户授权的个人信息

    public static String GETTOKEN_URL  = "https://oapi.dingtalk.com/gettoken";   //获取AccessToken

    public static String GETUSERDETAIL_URL = "https://oapi.dingtalk.com/user/get";   //获取成员详情

    public static String SIMPLELIST_USER_URL = "https://oapi.dingtalk.com/user/simplelist";

    public static String GETUSERIDBYUNIONID_URL = "https://oapi.dingtalk.com/user/getUseridByUnionid";   //根据unionid获取成员的userid

    public static String PROCESSINSTANCE_IDS_URL = "https://oapi.dingtalk.com/topapi/processinstance/listids";  //获取审批ids

    public static String PROCESSINSTANCE_DETAIL_URL = "https://oapi.dingtalk.com/topapi/processinstance/get";   //获取审批详情

    public static String DEPTLIST_URL = "https://oapi.dingtalk.com/department/list"; //获取部门列表

    public static String INSTANCECALLBACK = "/approve/instanceCallback";

    public static String REGISTER_CALL_BACK = "https://oapi.dingtalk.com/call_back/register_call_back";

    public static String UPDATE_CALL_BACK = "https://oapi.dingtalk.com/call_back/update_call_back";

    public static String MESSAGEAPI = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2";

    public static Long resCode = 0L;      //钉钉接口返回正常code

    public static Long GETPROJSTARTTIME = 1262275200000L;

    /**
     * 创建套件后，验证回调URL创建有效事件（第一次保存回调URL之前）
     */
    public static final String EVENT_CHECK_CREATE_SUITE_URL = "check_create_suite_url";
    /**
     * 创建套件后，验证回调URL变更有效事件（第一次保存回调URL之后）
     */
    public static final String EVENT_CHECK_UPADTE_SUITE_URL = "check_update_suite_url";

    public static final String BPMS_INSTANCE_CHANGE = "bpms_instance_change";

    public static final String BPMS_TASK_CHANGE = "bpms_task_change";

    public static final String REGISTAESKEY = "1234567890123456789012345678901234567890123";

    public static final String REGISTTOKEN = "123456";


    public static String SNS_ACCESS_TOKEN = "";

    public static String ACCESS_TOKEN = "";


    public static String APPID;
    public static String APPSECRET;
    public static String CORPID;
    public static String CORPSECRET;
    public static String PROCESSCODE; //新审批
    public static Long AGENTID;
    public static String DOMAIN;
    public static String ADRESS;


    @Value("${ding.APPID}")
    public void setAPPID(String APPID) {
        this.APPID = APPID;
    }
    @Value("${ding.APPSECRET}")
    public void setAPPSECRET(String APPSECRET) {
        this.APPSECRET = APPSECRET;
    }

    @Value("${ding.CORPID}")
    public void setCORPID(String CORPID) {
        this.CORPID = CORPID;
    }
    @Value("${ding.CORPSECRET}")
    public void setCORPSECRET(String CORPSECRET) {
        this.CORPSECRET = CORPSECRET;
    }
    @Value("${ding.PROCESSCODE}")
    public void setPROCESSCODE(String PROCESSCODE) {
        DTConstant.PROCESSCODE = PROCESSCODE;
    }
    @Value("${ding.AGENTID}")
    public void setAGENTID(String AGENTID) {
        DTConstant.AGENTID = Long.valueOf(AGENTID);
    }
    @Value("${ding.DOMAIN}")
    public void setDOMAIN(String DOMAIN) {
        DTConstant.DOMAIN = DOMAIN;
    }
    @Value("${ding.ADRESS}")
    public void setADRESS(String ADRESS) {
        DTConstant.ADRESS = ADRESS;
    }



    public static void getSnsToken() throws Exception{
        DingTalkClient client = new DefaultDingTalkClient(DTConstant.SNS_GETTOKEN_URL);
        OapiSnsGettokenRequest request = new OapiSnsGettokenRequest();
        request.setAppid(DTConstant.APPID);
        request.setAppsecret(DTConstant.APPSECRET);
        request.setHttpMethod("GET");
        OapiSnsGettokenResponse response = client.execute(request);
        DTConstant.SNS_ACCESS_TOKEN = response.getAccessToken();
    }

    public static void getAccesToken(){
        String requestUrl = GETTOKEN_URL;
        String result = HttpUtils.sendGet(requestUrl,"corpid="+CORPID+"&corpsecret="+CORPSECRET);
        JSONObject jsonObject = new JSONObject();
        jsonObject = JSON.parseObject(result);
        String msg = (String)jsonObject.get("errmsg");
        if("ok".equals(msg)){
            ACCESS_TOKEN = (String)jsonObject.get("access_token");
        }
    }


    //获取用户基本信息
    public static OapiUserGetResponse getUserDetailByUserId(String userId) throws Exception{
        DingTalkClient client = new DefaultDingTalkClient(GETUSERDETAIL_URL);
        OapiUserGetRequest request = new OapiUserGetRequest();
        request.setUserid(userId);
        request.setHttpMethod("GET");
        OapiUserGetResponse response = client.execute(request, ACCESS_TOKEN);
        return response;
    }

    //获取部门用户ids
    public static OapiUserSimplelistResponse userSimplelist(Long deptId) throws Exception{
        DingTalkClient client = new DefaultDingTalkClient(SIMPLELIST_USER_URL);
        OapiUserSimplelistRequest request = new OapiUserSimplelistRequest();
        request.setDepartmentId(deptId);
        request.setHttpMethod("GET");

        OapiUserSimplelistResponse response = client.execute(request, ACCESS_TOKEN);
        return response;
    }

    //获取所有部门
    public static OapiDepartmentListResponse getDepts() throws Exception{
        DingTalkClient client = new DefaultDingTalkClient(DEPTLIST_URL);
        OapiDepartmentListRequest request = new OapiDepartmentListRequest();
        request.setHttpMethod("GET");
        OapiDepartmentListResponse response = client.execute(request, ACCESS_TOKEN);
        return response;
    }

    //批量获取立项申请ids
    public static OapiProcessinstanceListidsResponse getInstanceIds(Long startTime, Long EndTime, Long size, Long cursor) throws Exception{
        DingTalkClient client = new DefaultDingTalkClient(PROCESSINSTANCE_IDS_URL);
        OapiProcessinstanceListidsRequest req = new OapiProcessinstanceListidsRequest();
        req.setProcessCode(PROCESSCODE);
        if(startTime == null){
            req.setStartTime(GETPROJSTARTTIME);
        }else {
            req.setStartTime(startTime);
        }
        req.setEndTime(EndTime);
        req.setSize(size);
        req.setCursor(cursor);
        OapiProcessinstanceListidsResponse response = client.execute(req, ACCESS_TOKEN);
        return response;
    }

    //获取立项申请ids
    public static void getProjIds(Set<String> ids, Long startTime, Long endTime, Long cursor) throws Exception{
        List<String> list;
        Long size = 10L;
        OapiProcessinstanceListidsResponse res = null;
        res = DTConstant.getInstanceIds(startTime,endTime,size,cursor);
        if(DTConstant.resCode.equals(res.getErrcode())){
            ids.addAll(res.getResult().getList());
            if(null!=res.getResult().getNextCursor()) {
                cursor = res.getResult().getNextCursor();
                getProjIds(ids,startTime,endTime,cursor);
            }
        }else {
            logger.error("getInstance接口获取失败");
            throw new Exception("getInstance接口获取失败");
        }
    }

    //获取立项申请详情
    public static OapiProcessinstanceGetResponse getProjectDetail(String projId) throws Exception{
        DingTalkClient client = new DefaultDingTalkClient(PROCESSINSTANCE_DETAIL_URL);
        OapiProcessinstanceGetRequest request = new OapiProcessinstanceGetRequest();
        request.setProcessInstanceId(projId);
        OapiProcessinstanceGetResponse response = client.execute(request,ACCESS_TOKEN);
        return response;
    }

    //新建
    public static OapiProcessinstanceCreateResponse createInstance(StringBuilder approveUsers,String userId,long deptId,List<OapiProcessinstanceCreateRequest.FormComponentValueVo> formComponentValues) throws Exception{
        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/create");
        OapiProcessinstanceCreateRequest request = new OapiProcessinstanceCreateRequest();
        request.setProcessCode(PROCESSCODE);
        request.setFormComponentValues(formComponentValues);
        request.setApprovers(approveUsers.toString());
        request.setOriginatorUserId(userId);
        request.setDeptId(deptId);
        OapiProcessinstanceCreateResponse response = client.execute(request,ACCESS_TOKEN);
        return response;
    }

    //注册回调事件
    public static void registInstance() throws Exception{
        DingTalkClient client = new DefaultDingTalkClient(REGISTER_CALL_BACK);
        OapiCallBackRegisterCallBackRequest request = new OapiCallBackRegisterCallBackRequest();
        request.setUrl(ADRESS+INSTANCECALLBACK);
        request.setAesKey(REGISTAESKEY);
        request.setToken(REGISTTOKEN);
        request.setCallBackTag(Arrays.asList("bpms_instance_change","bpms_task_change"));
        OapiCallBackRegisterCallBackResponse response = client.execute(request,ACCESS_TOKEN);
    }

    //更新回调事件
    public static void registUpdate() throws Exception{
        DingTalkClient  client = new DefaultDingTalkClient(UPDATE_CALL_BACK);
        OapiCallBackUpdateCallBackRequest request = new OapiCallBackUpdateCallBackRequest();
        request.setUrl(ADRESS+INSTANCECALLBACK);
        request.setAesKey(REGISTAESKEY);
        request.setToken(REGISTTOKEN);
        request.setCallBackTag(Arrays.asList("bpms_instance_change","bpms_task_change"));
        OapiCallBackUpdateCallBackResponse response = client.execute(request,ACCESS_TOKEN);
    }

    //消息模板
    public static boolean sendTemplet(String dUserId,String projName, String projCode,String projStatus) throws Exception{
        try {
            DingTalkClient client = new DefaultDingTalkClient(MESSAGEAPI);

            OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
            request.setUseridList(dUserId);
            request.setAgentId(AGENTID);
            request.setToAllUser(false);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
//            msg.setMsgtype("link");
//            msg.setLink(new OapiMessageCorpconversationAsyncsendV2Request.Link());
//            msg.getLink().setTitle("【智能数据工厂】 "+projName+" "+report+"进度更新通知");
//            msg.getLink().setText(sdf.format(new Date())+" "+projName+" "+report+"进度已更新");
//            msg.getLink().setMessageUrl(DOMAIN+"/routers/mainPage/main_baseMain");
//            msg.getLink().setPicUrl(DOMAIN+"/dingFront/static/public/images/login/logo_word.png");

            msg.setMsgtype("markdown");
            msg.setMarkdown(new OapiMessageCorpconversationAsyncsendV2Request.Markdown());
            msg.getMarkdown().setTitle("【智能数据工厂】 "+projName);
            msg.getMarkdown().setText("##### 【智能数据工厂】" + projName+" 项目已进入"+projStatus+"状态通知\n" +
                    "- 项目名称："+projName+"\n" +
                    "- 项目编号："+projCode+"\n" +
                    "- 项目状态："+projStatus+"\n" +
                    "- 更新时间："+sdf.format(new Date())+"\n" +
                    "\n" +
                    "请在PC端打开智能数据工厂查看");
            request.setMsg(msg);
            OapiMessageCorpconversationAsyncsendV2Response response = client.execute(request, ACCESS_TOKEN);
            if(response.getErrcode().equals(resCode)) {
                return true;
            }else {
                logger.error("消息接口sendReportMessage调用失败:"+response.getErrmsg());
                return false;
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error("消息发送失败");
            return false;
        }
    }


    public static boolean sendMes(String dUserId,String content) throws Exception{
        try {
            DingTalkClient client = new DefaultDingTalkClient(MESSAGEAPI);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
            request.setUseridList(dUserId);
            request.setAgentId(AGENTID);
            request.setToAllUser(false);
            OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
            msg.setMsgtype("text");
            msg.setText(new OapiMessageCorpconversationAsyncsendV2Request.Text());
            msg.getText().setContent(content);
            request.setMsg(msg);
            OapiMessageCorpconversationAsyncsendV2Response response = client.execute(request, ACCESS_TOKEN);
            if(response.getErrcode().equals(resCode)) {
                return true;
            }else {
                logger.error("消息接口sendMes调用失败:"+response.getErrmsg());
                return false;
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error("撤销消息发送失败");
            return false;
        }
    }


    //上传文件到存储服务器
    public static void uploadToStore() throws Exception{
        OapiFileUploadSingleRequest request = new OapiFileUploadSingleRequest();
        request.setFileSize(1000L);
        request.setAgentId("212149767");
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/file/upload/single?"+WebUtils.buildQuery(request.getTextParams(),"utf-8"));
        // 必须重新new一个请求
        request = new OapiFileUploadSingleRequest();
        request.setFile(new FileItem("D:/1.png"));
        OapiFileUploadSingleResponse response = client.execute(request,DTConstant.ACCESS_TOKEN);
        //response 可以获取到文件的 mediaId
    }

    //上传存储服务器文件到钉盘
    public static void uploadToDingSpace() throws Exception{
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/cspace/add");
        OapiCspaceAddRequest request = new OapiCspaceAddRequest();
        request.setAgentId("");
        request.setCode("3f6784e23a5b3a34872cb14123259fe7");    //jsapi获取
        request.setMediaId("#iAEHAqRmaWxlA6h5dW5kaXNrMATOCw_n8wXOAAFyIAbNCxcHzlxFjQwIzQGz");
        request.setSpaceId("1209805482"); //jsapi获取
        request.setFolderId(""); //dirId jsapi获取
        request.setName("test.png");
        request.setOverwrite(true);
        request.setHttpMethod("GET");
        OapiCspaceAddResponse response = client.execute(request,DTConstant.ACCESS_TOKEN);

    }

}
